home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-28 | 22.6 KB | 914 lines | [TEXT/MPS ] |
- /*
- File: Window.cp
-
- Contains: Implementation of TWindow, a base class which provides a
- framework for building way-cool windows which even John
- Sullivan would be happy with. Floating windows and “smart
- zooming” algorithms are based on code samples provided by
- Dean Yu. Tim Craycroft, the guy making the window manager
- do all this work for you has also been a great help.
-
- Written by: Dave Falkenburg
-
- Copyright: © 1993-94 by Dave Falkenburg, all rights reserved.
-
- Change History (most recent first):
-
- <8> 11/17/94 DRF Add casts for CFront & PPCC. Also dealt with the change to
- ClipAbove in the latest universal headers.
- <7> 11/12/94 DRF Added AdjustMenusBeforeMenuSelection.
- <6> 11/8/94 DRF Add some better menu handling methods.
- <5> 9/27/94 DRF AppLib.h is now Sprocket.h
- <4> 9/9/94 DRF Reorganized headers and removed redundant #includes.
- <3> 9/4/94 DRF Added DrawJustTheGrowIcon.
- <2> 8/27/94 DRF In TWindow::Close, call window’s (de)Activate method before
- closing so that menus can be properly updated.
-
- To Do: Make sure invisible windows can be created & managed
- Handle modal windows as another class of windows
- Fix activate bugs when showing and hiding windows
- Window positioning methods (getters and setters)
- Display Manager support
- Changes to support AEObject model
- */
-
- #include "Sprocket.h"
- #include "Window.h"
-
- #include <Script.h> // for GetMBarHeight()
- #include <LowMem.h> // for LMGetWindowList()
-
-
- const short kFloatingWindowKind = 1000;
- const short kNormalWindowKind = 1001;
- const WindowPtr kNoFloatingWindows = (WindowPtr) -1;
-
- const short kScreenEdgeSlop = 4;
- const short kSpaceForFinderIcons = 64;
- const short kMinimumTitleBarHeight = 21;
- const short kMinimumWindowSize = 32;
-
- static void HiliteShowHideFloatingWindows(Boolean hiliting,Boolean hiding);
-
- static void FindScreenRectWithLargestPartOfWindow(WindowPtr aWindow,Rect *theBestScreenRect, GDHandle * theBestDevice);
- static pascal void CalculateWindowAreaOnDevice(short depth,short deviceFlags,GDHandle targetDevice,long userData);
-
-
- struct CalcWindowAreaDeviceLoopUserData
- {
- GDHandle fScreenWithLargestPartOfWindow;
- long fLargestArea;
- Rect fWindowBounds;
- };
-
-
-
-
-
- TWindow::TWindow()
- {
- }
-
-
- TWindow::~TWindow()
- {
- }
-
-
- void
- TWindow::CreateWindow(WindowType typeOfWindowToCreate /* = kNormalWindow */)
- {
- WindowPtr behindWindow,oldFrontMostWindow;
-
- if (typeOfWindowToCreate == kModalWindow)
- {
- DebugStr((StringPtr) "\pModal windows aren’t supported yet");
- fWindowType = kFloatingWindow;
- return;
- }
- else if (typeOfWindowToCreate == kFloatingWindow)
- {
- behindWindow = (WindowPtr) -1;
- oldFrontMostWindow = FrontWindow();
-
- fWindowType = kFloatingWindow;
- }
- else if (typeOfWindowToCreate == kNormalWindow)
- {
- behindWindow = LastFloatingWindow();
-
- fWindowType = kNormalWindow;
-
- if (behindWindow == kNoFloatingWindows)
- oldFrontMostWindow = nil;
- else
- oldFrontMostWindow = (WindowPtr) ((WindowPeek) behindWindow)->nextWindow;
- }
-
- fWindow = this->MakeNewWindow(behindWindow);
- fIsVisible = ((WindowPeek) fWindow)->visible;
-
- if (fWindow)
- {
- SetWRefCon(fWindow,(long) this);
-
- if (typeOfWindowToCreate == kModalWindow)
- {
- DebugStr((StringPtr) "\pCan’t create Modal windows yet");
- }
- else if (typeOfWindowToCreate == kFloatingWindow)
- {
- ((WindowPeek) fWindow)->windowKind = kFloatingWindowKind;
-
- // make sure the other window stays hilited
- if (oldFrontMostWindow)
- HiliteAndActivateWindow(oldFrontMostWindow,true);
- }
- else if (typeOfWindowToCreate == kNormalWindow)
- {
- ((WindowPeek) fWindow)->windowKind = kNormalWindowKind;
-
- // unhighlight the old front window
- if (oldFrontMostWindow)
- HiliteAndActivateWindow(oldFrontMostWindow,false);
-
- // hilite the new window…
- HiliteAndActivateWindow(fWindow,true);
- }
- }
- }
-
-
- void
- TWindow::AdjustCursor(EventRecord * /* anEvent */)
- {
- }
-
- void
- TWindow::Idle(EventRecord * /* anEvent */)
- {
- }
-
- void
- TWindow::Activate(Boolean /* activating */)
- {
- }
-
- void
- TWindow::Draw(void)
- {
- }
-
- void
- TWindow::Click(EventRecord * /* anEvent */)
- {
- }
-
- void
- TWindow::KeyDown(EventRecord * /* anEvent */)
- {
- }
-
-
- void
- TWindow::Select(void)
- {
- WindowPtr currentFrontWindow;
-
- if (fWindowType == kFloatingWindow)
- currentFrontWindow = FrontWindow();
- else if (fWindowType == kNormalWindow)
- currentFrontWindow = FrontNonFloatingWindow();
- else
- {
- }
-
- if (currentFrontWindow != fWindow)
- {
- if (fWindowType == kFloatingWindow)
- BringToFront(fWindow);
- else
- {
- WindowPtr lastFloater = LastFloatingWindow();
-
- // If there are no floating windows,
- // just call SelectWindow like the good ol’ days
-
- if (lastFloater == kNoFloatingWindows)
- SelectWindow(fWindow);
- else
- {
- // Deactivate the window currently in front.
-
- HiliteAndActivateWindow(currentFrontWindow,false);
-
- // Bring it behind the last floating window and activate it.
- // Note that Inside Mac 1 states that you need to call PaintOne() and CalcVis() on a
- // window if you are using SendBehind() to bring it closer to the front. With System 7,
- // this is no longer necessary.
-
- SendBehind(fWindow,lastFloater);
- HiliteAndActivateWindow(fWindow,true);
- }
- }
- }
- }
-
-
- void
- TWindow::Drag(Point startPoint)
- {
- GrafPtr savePort;
- KeyMap theKeyMap;
- Boolean commandKeyDown = false;
- RgnHandle draggingRegion;
- long dragResult;
- WindowPeek windowAsWindowPeek = (WindowPeek) fWindow;
-
- if (WaitMouseUp()) // de-bounce?
- {
- // Set up the Window Manager port.
-
- GetPort(&savePort);
- SetPort(gWindowManagerPort);
- SetClip(GetGrayRgn());
-
- // Check to see if the command key is down.
-
- GetKeys(theKeyMap);
- commandKeyDown = ((theKeyMap[1] & 0x8000) != 0);
-
- if (commandKeyDown)
- {
- // We’re not going to change window ordering,
- // so make sure that we don’t drag in front of
- // other windows which may be in front of ours.
-
- // 11/16/94 <Windows.h> on ETO defines this routine to take
- // a WindowPtr instead of a WindowPeek. When building
- // with new headers (like those included with ETO 16)
- // make sure to define USEOLDUNIVERSALHEADERS to 0.
-
- #if USEOLDUNIVERSALHEADERS
- ClipAbove(windowAsWindowPeek);
- #else
- ClipAbove((WindowPtr) windowAsWindowPeek);
- #endif
- }
- else if (fWindowType != kFloatingWindow)
- {
- // We’re dragging a normal window, so make sure
- // that we don’t drag in front of any floating
- // windows.
-
- // 11/16/94 <Windows.h> on ETO defines this routine to take
- // a WindowPtr instead of a WindowPeek. When building
- // with new headers (like those included with ETO 16)
- // make sure to define USEOLDUNIVERSALHEADERS to 0.
-
- #if USEOLDUNIVERSALHEADERS
- ClipAbove((WindowPeek) FrontNonFloatingWindow());
- #else
- ClipAbove(FrontNonFloatingWindow());
- #endif
- }
-
- // Drag an outline of the window around the desktop.
- // NOTE: DragGrayRgn destroys the region passed in, so make a copy
-
- draggingRegion = NewRgn();
- CopyRgn(windowAsWindowPeek->strucRgn,draggingRegion);
- dragResult = DragGrayRgn(draggingRegion, startPoint, &gDeskRectangle, &gDeskRectangle, noConstraint, nil);
- DisposeRgn(draggingRegion);
-
-
- SetPort(savePort); // Get back to old port
-
- if ((dragResult != 0) && (dragResult != 0x80008000))
- {
- this->Nudge((short) (dragResult & 0xFFFF),(short) (dragResult >> 16));
- }
- }
-
- if (!commandKeyDown)
- Select();
- }
-
- void
- TWindow::Nudge(short horizontalDistance, short verticalDistance)
- {
- WindowPeek windowAsWindowPeek = (WindowPeek) fWindow;
- short newHorizontalPosition,newVerticalPosition;
-
- newHorizontalPosition = (short) (**windowAsWindowPeek->contRgn).rgnBBox.left + horizontalDistance;
- newVerticalPosition = (short) (**windowAsWindowPeek->contRgn).rgnBBox.top + verticalDistance;
-
- MoveWindow(fWindow,newHorizontalPosition,newVerticalPosition,false);
- }
-
- void
- TWindow::Grow(Point startPoint)
- {
- GrafPtr oldPort;
- long newSize;
- Rect oldWindowRect,resizeLimits;
-
- GetPort(&oldPort);
-
- GetWindowSizeLimits(&resizeLimits);
- newSize = GrowWindow(fWindow,startPoint,&resizeLimits);
- if (newSize)
- {
- oldWindowRect = fWindow->portRect;
- SizeWindow(fWindow,(short) newSize,(short) (newSize >> 16),true);
- SetPort(fWindow);
- this->AdjustForNewWindowSize(&oldWindowRect,&fWindow->portRect);
- }
-
- SetPort(oldPort);
- }
-
-
- void
- TWindow::Zoom(short zoomState)
- {
- GrafPtr oldPort;
- FontInfo systemFontInfo;
- short titleBarHeight;
- Rect bestScreenRect,perfectWindowRect,scratchRect;
- short amountOffscreen;
- WindowPeek windowAsWindowPeek = (WindowPeek) fWindow;
- GDHandle bestDevice;
-
- GetPort(&oldPort);
-
- // Figure out the height of the title bar so we can properly position
- // a window. The algorithm is stolen from the System 7.x 'WDEF' (0)
- //
- // This probably isn’t the best thing to do: A better way might be
- // to diff the structure and content region rectangles?
-
- SetPort(gWindowManagerPort);
- GetFontInfo(&systemFontInfo);
- titleBarHeight = (short) (systemFontInfo.ascent + systemFontInfo.descent + 4);
- if ((titleBarHeight % 2) == 1)
- titleBarHeight--;
- if (titleBarHeight < kMinimumTitleBarHeight)
- titleBarHeight = kMinimumTitleBarHeight;
-
-
- // Only do the voodoo magic if we are really “zooming” the window.
-
- if (zoomState == inZoomOut)
- {
- FindScreenRectWithLargestPartOfWindow(fWindow,&bestScreenRect,&bestDevice);
- bestScreenRect.top += titleBarHeight;
-
- this->GetPerfectWindowSize(&perfectWindowRect);
- OffsetRect(&perfectWindowRect,-perfectWindowRect.left,-perfectWindowRect.top);
-
- // Take the zero-pined perfect window size and move it to
- // the top left of the window’s content region.
-
- OffsetRect(&perfectWindowRect,(**windowAsWindowPeek->contRgn).rgnBBox.left,
- (**windowAsWindowPeek->contRgn).rgnBBox.top);
-
-
- // Does perfectWindowRect fit completely on the best screen?
-
- SectRect(&perfectWindowRect, &bestScreenRect, &scratchRect);
- if (!EqualRect(&perfectWindowRect, &scratchRect))
- {
- // SectRect sez perfectWindowRect doesn’t completely fit
- // on the screen, so bump the window so that more of it fits.
-
- // Make sure that the left edge of perfectWindowRect is forced
- // onto the best screen. This is in case we are bumping
- // the window to the right.
-
- amountOffscreen = bestScreenRect.left - perfectWindowRect.left;
- if (amountOffscreen > 0)
- {
- perfectWindowRect.left += amountOffscreen;
- perfectWindowRect.right += amountOffscreen;
- }
-
- // Make sure that the left edge of perfectWindowRect is forced
- // onto the best screen. This is in case we are bumping
- // the window downward to a new screen.
-
- amountOffscreen = bestScreenRect.top - perfectWindowRect.top;
- if (amountOffscreen > 0)
- {
- perfectWindowRect.top += amountOffscreen;
- perfectWindowRect.bottom += amountOffscreen;
- }
-
- // If right edge of window falls off the screen,
- // Move window to the left until the right edge IS on the screen
- // OR the left edge is at bestScreenRect.left
-
- amountOffscreen = perfectWindowRect.right - bestScreenRect.right;
- if (amountOffscreen > 0)
- {
- // Are we going to push the left edge offscreen? If so, change the
- // offset so we move the window all the way over to the left.
-
- if ((perfectWindowRect.left - amountOffscreen) < bestScreenRect.left)
- amountOffscreen = perfectWindowRect.left - bestScreenRect.left;
-
- perfectWindowRect.left -= amountOffscreen;
- perfectWindowRect.right -= amountOffscreen;
- }
-
- // If bottom edge of window falls off the screen,
- // Move window to up until the bottom edge IS on the screen
- // OR the top edge is at bestScreenRect.top
-
- amountOffscreen = perfectWindowRect.bottom - bestScreenRect.bottom;
- if (amountOffscreen > 0)
- {
- // Are we going to push the top edge offscreen? If so, change the
- // offset so we move the window just to the top.
-
- if ((perfectWindowRect.top - amountOffscreen) < bestScreenRect.top)
- amountOffscreen = perfectWindowRect.top - bestScreenRect.top;
-
- perfectWindowRect.top -= amountOffscreen;
- perfectWindowRect.bottom -= amountOffscreen;
- }
-
- SectRect(&perfectWindowRect, &bestScreenRect, &scratchRect);
- if (!EqualRect(&perfectWindowRect, &scratchRect))
- {
- // The edges of the window still fall offscreen,
- // so make the window smaller until it fits.
-
- if (perfectWindowRect.bottom > bestScreenRect.bottom)
- perfectWindowRect.bottom = bestScreenRect.bottom;
-
- // If the right edge is still falling off,
- // save space for Finder’s disk icons as well.
-
- if (perfectWindowRect.right > bestScreenRect.right)
- {
- perfectWindowRect.right = bestScreenRect.right;
-
- // If we were on the main screen, leave room for Finder icons, too.
-
- if (bestDevice == GetMainDevice())
- perfectWindowRect.right -= kSpaceForFinderIcons;
- }
- }
- }
-
- // Stash our new rectangle inside of the Window’s dataHandle
- // so that ZoomWindow does the right thing.
-
- (**((WStateDataHandle) (windowAsWindowPeek->dataHandle))).stdState = perfectWindowRect;
- }
-
- // HEY YOU! Don’t forget to set the port to the window being zoomed
- // Why, you ask? Because IM-IV-50 says to; otherwise you die
-
- SetPort(fWindow);
-
- Rect oldWindowRect = fWindow->portRect;
-
- ZoomWindow(fWindow,zoomState,false);
- this->AdjustForNewWindowSize(&oldWindowRect,&fWindow->portRect);
-
- SetPort(oldPort);
- }
-
- void
- TWindow::ShowHide(Boolean showFlag)
- {
- // Here we need the “::” in front of ShowHide to indicate we are calling
- // the global function, and not the method ShowHide. Unintended recursion
- // can do bad things to the unsuspecting programmer.
-
- // Some C++ programmers would always prepend the “::” on function calls.
-
- ::ShowHide(fWindow,showFlag);
- fIsVisible = showFlag;
- }
-
-
- Boolean
- TWindow::EventFilter(EventRecord * /* theEvent */)
- {
- return false;
- }
-
-
- void
- TWindow::GetPerfectWindowSize(Rect *perfectSize)
- {
- *perfectSize = qd.screenBits.bounds;
- }
-
- void
- TWindow::GetWindowSizeLimits(Rect *limits)
- {
- limits->top = limits->left = kMinimumWindowSize;
- limits->right = gDeskRectangle.right - gDeskRectangle.left;
- limits->bottom = gDeskRectangle.bottom - gDeskRectangle.top;
- }
-
- void
- TWindow::AdjustForNewWindowSize(Rect * /* oldRect */, Rect * /* newSize */)
- {
- }
-
-
- Boolean
- TWindow::IsVisible(void)
- {
- return fIsVisible;
- }
-
-
- Boolean
- TWindow::CanClose(void)
- {
- return true;
- }
-
-
- Boolean
- TWindow::Close(void)
- {
- WindowPtr newFrontWindow = nil;
-
- if (FrontNonFloatingWindow() == fWindow)
- newFrontWindow = (WindowPtr) ((WindowPeek) fWindow)->nextWindow;
-
- this->Activate(false);
- DisposeWindow(fWindow);
-
- if (newFrontWindow)
- HiliteAndActivateWindow(newFrontWindow,true);
-
- return true;
- }
-
-
- Boolean
- TWindow::DeleteAfterClose(void)
- {
- return true;
- }
-
-
- void
- TWindow::AdjustMenusBeforeMenuSelection(void)
- {
- }
-
-
- void
- TWindow::DoMenuSelection(short /* menu */, short /* item */)
- {
- }
-
-
- void
- TWindow::DoMenuCommand(unsigned long /* menuCommand */)
- {
- }
-
-
- OSErr
- TWindow::HandleDrag(DragTrackingMessage dragMessage,DragReference theDrag)
- {
- OSErr result = dragNotAcceptedErr;
-
- switch (dragMessage)
- {
- case dragTrackingEnterWindow:
- result = this->DragEnterWindow(theDrag);
- break;
-
- case dragTrackingInWindow:
- result = this->DragInWindow(theDrag);
- break;
-
- case dragTrackingLeaveWindow:
- result = this->DragLeaveWindow(theDrag);
- break;
-
- default:
- break;
- }
-
- return result;
- }
-
-
- OSErr
- TWindow::DragEnterWindow(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- OSErr
- TWindow::DragInWindow(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- OSErr
- TWindow::DragLeaveWindow(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- OSErr
- TWindow::HandleDrop(DragReference /* theDrag */)
- {
- return dragNotAcceptedErr;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // Utility Functions used for floating windows
- //
-
- TWindow *
- GetWindowObject(WindowPtr aWindow)
- {
- short wKind;
-
- if (aWindow != nil)
- {
- wKind = ((WindowPeek) aWindow)->windowKind;
-
- if (wKind >= userKind)
- {
- // All windowKinds >= userKind are based upon TWindow
-
- return (TWindow *) GetWRefCon(aWindow);
- }
- }
- return (TWindow *) nil;
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Utility functions
-
-
- pascal WindowPtr
- GetNewColorOrBlackAndWhiteWindow(short windowID, void *wStorage, WindowPtr behind)
- {
- if (gHasColorQuickdraw)
- return GetNewCWindow(windowID,wStorage,behind);
- else
- return GetNewWindow(windowID,wStorage,behind);
- }
-
-
- pascal WindowPtr
- NewColorOrBlackAndWhiteWindow(void *wStorage, const Rect *boundsRect, ConstStr255Param title, Boolean visible, short theProc, WindowPtr behind, Boolean goAwayFlag, long refCon)
- {
- if (gHasColorQuickdraw)
- return NewCWindow(wStorage,boundsRect,title,visible,theProc,behind,goAwayFlag,refCon);
- else
- return NewWindow(wStorage,boundsRect,title,visible,theProc,behind,goAwayFlag,refCon);
- }
-
-
- void
- DrawJustTheGrowIcon(WindowPtr aWindow)
- {
- GrafPtr savedPort;
- RgnHandle savedClip = NewRgn();
- Rect growBoxRect;
-
- GetPort(&savedPort);
- SetPort(aWindow);
- GetClip(savedClip);
-
- // clip to just the bottom right corner of the window
-
- growBoxRect.top = aWindow->portRect.bottom - kScrollbarWidth;
- growBoxRect.bottom = aWindow->portRect.bottom;
- growBoxRect.left = aWindow->portRect.right - kScrollbarWidth;
- growBoxRect.right = aWindow->portRect.right;
- ClipRect(&growBoxRect);
-
- DrawGrowIcon(aWindow);
-
- SetClip(savedClip);
- DisposeRgn(savedClip);
-
- SetPort(savedPort);
- }
-
-
- WindowPtr
- LastFloatingWindow(void)
- {
- WindowPeek aWindow = (WindowPeek) FrontWindow();
- WindowPtr lastFloater = (WindowPtr) kNoFloatingWindows;
-
- while (aWindow && (aWindow->windowKind == kFloatingWindowKind))
- {
- if (aWindow->visible)
- lastFloater = (WindowPtr) aWindow;
-
- aWindow = (WindowPeek) aWindow->nextWindow;
- }
- return(lastFloater);
- }
-
-
- WindowPtr
- FrontNonFloatingWindow(void)
- {
- WindowPeek aWindow = (WindowPeek) LMGetWindowList();
-
- // Skip over floating windows
-
- while (aWindow && (aWindow->windowKind == kFloatingWindowKind))
- aWindow = (WindowPeek) aWindow->nextWindow;
-
- // Skip over invisible, but otherwise normal windows
-
- while (aWindow && (aWindow->visible == 0))
- aWindow = (WindowPeek) aWindow->nextWindow;
-
- return (WindowPtr) aWindow;
- }
-
-
- void
- HiliteAndActivateWindow(WindowPtr aWindow,Boolean active)
- {
- GrafPtr oldPort;
- TWindow * wobj = GetWindowObject(aWindow);
-
- if (aWindow)
- {
- HiliteWindow(aWindow,active);
-
- if (wobj != nil)
- {
- GetPort(&oldPort);
- SetPort(aWindow);
- wobj->Activate(active);
- SetPort(oldPort);
- }
- }
- }
-
- void
- SuspendResumeWindows(Boolean resuming)
- {
- // When we suspend/resume, hide/show all the visible floaters
-
- HiliteShowHideFloatingWindows(resuming,true);
- }
-
- void
- HiliteWindowsForModalDialog(Boolean hiliting)
- {
- // When we display a modal dialog, we need to unhighlight
- // all visible floaters. We also need to re-hilite them
- // afterwards.
-
- HiliteShowHideFloatingWindows(hiliting,false);
- }
-
- void
- HiliteShowHideFloatingWindows(Boolean hiliting,Boolean dohiding)
- {
- WindowPeek aWindow;
- TWindow * wobj;
-
- HiliteAndActivateWindow(FrontNonFloatingWindow(),hiliting);
-
- aWindow = (WindowPeek) LMGetWindowList();
- while (aWindow && aWindow->windowKind == kFloatingWindowKind)
- {
- wobj = GetWindowObject((WindowPtr) aWindow);
-
- // If we are hiding or showing, only hide/show windows
- // that were visible to begin with.
-
- // NOTE: We use our copy of the visible flag so we can
- // automatically show floaters on a resume event.
-
- // NOTE: Since this isn’t a method of TWindow, we don’t
- // really need the “::” on ShowHide, but as long
- // as we’re trying to avoid ambiguity.
-
- if (dohiding && (wobj != nil) && (wobj->IsVisible()))
- ::ShowHide((WindowPtr) aWindow,hiliting);
-
- // All floaters are hilited if any floater is hilited
-
- HiliteWindow((WindowPtr) aWindow,hiliting);
- aWindow = (WindowPeek) aWindow->nextWindow;
- }
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // Routines used for dealing with windows and multiple screens
- //
-
- pascal void
- CalculateWindowAreaOnDevice(short /* depth */,short /* deviceFlags */,GDHandle targetDevice,long userData)
- {
- CalcWindowAreaDeviceLoopUserData * deviceLoopDataPtr;
- long windowAreaOnThisScreen;
- Rect windowRectOnThisScreen;
-
- deviceLoopDataPtr = (CalcWindowAreaDeviceLoopUserData *) userData;
-
- SectRect(&deviceLoopDataPtr->fWindowBounds, &(**targetDevice).gdRect,&windowRectOnThisScreen);
- OffsetRect(&windowRectOnThisScreen,-windowRectOnThisScreen.left,-windowRectOnThisScreen.top);
- windowAreaOnThisScreen = windowRectOnThisScreen.right * windowRectOnThisScreen.bottom;
-
- if (windowAreaOnThisScreen > deviceLoopDataPtr->fLargestArea)
- {
- deviceLoopDataPtr->fLargestArea = windowAreaOnThisScreen;
- deviceLoopDataPtr->fScreenWithLargestPartOfWindow = targetDevice;
- }
- }
-
-
- DeviceLoopDrawingUPP CallCalcWindowAreaOnDevice = NewDeviceLoopDrawingProc(&CalculateWindowAreaOnDevice);
-
-
- void
- FindScreenRectWithLargestPartOfWindow(WindowPtr aWindow,Rect *theBestScreenRect,GDHandle * theBestDevice)
- {
- RgnHandle copyOfWindowStrucRgn;
- CalcWindowAreaDeviceLoopUserData deviceLoopData;
-
- // Use DeviceLoop to find out what GDevice contains the largest
- // portion of the supplied window.
- //
- // NOTE: Assumes thePort == the Window Manager Port because we using
- // the window strucRgn, not contRgn.
-
- deviceLoopData.fScreenWithLargestPartOfWindow = nil;
- deviceLoopData.fLargestArea = -1;
- deviceLoopData.fWindowBounds = (**(((WindowPeek) aWindow)->contRgn)).rgnBBox;
-
- copyOfWindowStrucRgn = NewRgn();
- CopyRgn(((WindowPeek) aWindow)->strucRgn,copyOfWindowStrucRgn);
-
- DeviceLoop(copyOfWindowStrucRgn,CallCalcWindowAreaOnDevice,(long) &deviceLoopData,singleDevices);
-
- DisposeRgn(copyOfWindowStrucRgn);
-
- *theBestDevice = deviceLoopData.fScreenWithLargestPartOfWindow;
- *theBestScreenRect = (**(deviceLoopData.fScreenWithLargestPartOfWindow)).gdRect;
-
- // Leave some space around the edges of the screen so window look good, AND
- // if the best device is the main screen, leave space for the Menubar
-
- InsetRect(theBestScreenRect,kScreenEdgeSlop,kScreenEdgeSlop);
- if (GetMainDevice() == deviceLoopData.fScreenWithLargestPartOfWindow)
- theBestScreenRect->top += GetMBarHeight();
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // Drag Manager callback routines which dispatch to a window’s method
- //
-
- pascal OSErr
- CallWindowDragTrackingHandler(DragTrackingMessage dragMessage,WindowPtr theWindow,void * /* refCon */,DragReference theDrag)
- {
- TWindow *wobj = GetWindowObject(theWindow);
-
- if (wobj)
- return(wobj->HandleDrag(dragMessage,theDrag));
- else
- return dragNotAcceptedErr;
- }
-
-
- pascal OSErr
- CallWindowDragReceiveHandler(WindowPtr theWindow,void * /* refCon */,DragReference theDrag)
- {
- TWindow *wobj = GetWindowObject(theWindow);
-
- if (wobj)
- return(wobj->HandleDrop(theDrag));
- else
- return dragNotAcceptedErr;
- }
-